/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package gujproject;

import java.io.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.bcharris.trie.*;


/**
 *
 * @author achal
 */
public class MorphoClass {

    public String identifyNounGender(String current)
    {
        Pattern p=Pattern.compile(".*\u0A93|\u0ACB$");
        Matcher m=p.matcher(current);
        if(m.matches())
        {
            current=current.concat("_M");
            return(current);
        }
        p=Pattern.compile("(\u0AC0\u0A93$)|(\u0A88\u0A93$)");
        m=p.matcher(current);
        if(m.matches())
        {
            current=current.concat("_F");
            return(current);
        }
        return current;

    }


    public boolean identifyKrudanth(String sample)
    {
        Pattern p=Pattern.compile(".*\u0AA4(\u0ACB|\u0AC0|\u0AC1|\u0ABE)");
        Matcher m;
        m=p.matcher(sample);
        if(m.matches())
            return true;
        else
            return false;
    }


    public void analyzeMorphology()
    {
        File corpusFile=new File("corpus.txt");
        File lexiconFile=new File("lexicon.txt");

        Map<String, Integer> Lexicon=new HashMap<String, Integer>();
        String WordOccur=new String();
        String [] Word=null;
        String stringLine=new String();
        int Occurrence, i, flag;

        String []temp=null;


        String nounEnders="\u0AA8\u0ABE";
        String verbEnders="\u0AB5\u0AC1";
        String singleWord;

        Pattern p=Pattern.compile("[\u0A80-\u0AFF]+");
        Matcher nounMatcher;
        Matcher verbMatcher;

        //Rules for morphology of suffixes of verbs
        HashMap verbEndingRules=new HashMap();



        //Rules for morphology for suffixes of nouns
        HashMap nounEndingRules=new HashMap();

        nounEndingRules.put("\u0ACB", "NOM_M_SING");
        nounEndingRules.put("\u0AC1", "NOM_N_SING");
        nounEndingRules.put("\u0AC0", "NON_F_SING");

        String nounRuleEnders=new String(".+(\u0ACB");

        for(Iterator nounIterator=nounEndingRules.keySet().iterator();nounIterator.hasNext();)
        {
            nounRuleEnders=nounRuleEnders.concat("|");
            nounRuleEnders=nounRuleEnders.concat(nounIterator.next().toString());

        }

        nounRuleEnders=nounRuleEnders.concat(")$");
        System.out.println(nounRuleEnders);
        Pattern nounEndingPattern=Pattern.compile(nounRuleEnders);


        try
        {

        BufferedReader corpusBuff=new BufferedReader(new FileReader(corpusFile));
        BufferedReader lexiconBuff=new BufferedReader(new FileReader(lexiconFile));

        System.out.println(lexiconBuff.readLine());

        while((WordOccur=lexiconBuff.readLine())!=null)
        {
            Word=WordOccur.split(" ");

            if(Word.length<2)
            {
                continue;
            }

            Occurrence= Integer.parseInt(Word[1]);
            Lexicon.put(Word[0], Occurrence);
        }

        lexiconBuff.close();

        while((stringLine=corpusBuff.readLine())!=null)
        {
                            temp=stringLine.split(" ");
                            for(int j=0;j<temp.length;j++)
                            {



                                String current=temp[j];
                                p=Pattern.compile("[\u0A80-\u0AFF]+");
                                Matcher m=p.matcher(current);
                                if(m.matches()==false)
                                {
                                    continue;
                                }


                                if(current.length()<=2)
                                {
                                    break;
                                }
                                else if(current.length()<4)
                                {
                                    i=1;
                                }
                                else
                                {
                                    i=2;
                                }



                                //Check for noun

                                String nounregex=current.substring(0, current.length()-i);
                                String verbregex=current.substring(0,current.length()-i);



                                nounregex=nounregex.concat("[\\u0A80-\\u0AFF]*");
                                nounregex=nounregex.concat(nounEnders);
                                //System.out.println(regex);
                                Pattern thisNoun=Pattern.compile(nounregex);
                                verbregex=current.substring(0, current.length()-i);
                                verbregex=verbregex.concat("[\u0A80-\u0AFF]*");
                                verbregex=verbregex.concat(verbEnders);
                                Pattern thisVerb=Pattern.compile(verbregex);


//                               System.out.println(current);

                                for(Iterator wordIterator=Lexicon.keySet().iterator();wordIterator.hasNext();)
                                {

                                    flag=0;
                                    singleWord=wordIterator.next().toString();

                                    nounMatcher=thisNoun.matcher(singleWord);

                                    if(nounMatcher.matches())
                                    {
                                        //System.out.println(current+"_N_"+singleWord);
                                        m=nounEndingPattern.matcher(current);
                                        if(m.matches())
                                        {
                                            String returned=identifyNounGender(current);

                                              System.out.println(current+"_N_"+nounEndingRules.get(current.substring(current.length()-1, current.length())));
                                              System.out.println(returned);
  //                                          obuff.write(current+"_N_"+singleWord+"\n");
                                        }

                                        flag=1;

                                    }

                                     verbMatcher=thisVerb.matcher(singleWord);
                                    if(verbMatcher.matches())
                                    {
                              //          System.out.println(current+"_V_"+singleWord);
      //                                  obuff.write(current+"_V_"+singleWord+"\n");

                                    }

                                    if(flag==1)
                                    {
                                        continue;
                                    }
                                }



                                //Assumes


            }
        }


        } catch(FileNotFoundException ex)
        {
            ex.printStackTrace();
            System.out.println("File not found\n");
        }catch(IOException ex)
        {
            ex.printStackTrace();
        }

    }


    public void getInfoContent(double alpha, double beta, double gamma)
    {
        getInfoContent(alpha, beta, gamma, "texicon.txt", "lexicon.txt");
    }

    public void getInfoContent(double alpha, double beta, double gamma, String lexFile, String testFile)
    {
        File lexicon =new File(lexFile);
        File testDataFile=new File(testFile);
        File results =new File("resultsA"+alpha+"B"+beta+"G"+gamma);
        ViewableTrie wordsTrie=new ViewableTrie(false);
        ViewableTrie revTrie=new ViewableTrie(false);

        BufferedWriter obuff;

        String strLine=new String();
        String []temp=null;
        String reverse=new String();

        int kids, kidsofkid, maxKidDiff, kidDiff, kidLength;
        int i, j, infoLength, infoRev, maxInfoRev;
        int infoNormal, maxInfoNormal;
        int length=0;
        int height;

        double m, maxM;

        try
        {



            
            BufferedReader lexBuff=new BufferedReader(new FileReader(lexicon));
            obuff=new BufferedWriter(new FileWriter(results));

            while((strLine=lexBuff.readLine())!=null)
            {
                temp=strLine.split(" ");

                for(i=0;i<temp.length;i++)
                {
                    for(j=1;j<temp[i].length();j++)

                    {
                        wordsTrie.insert(temp[i].substring(0, j));
                    }
                    reverse=new StringBuffer(temp[i]).reverse().toString();

                    for(j=1;j<reverse.length();j++)
                    {
                        revTrie.insert(reverse.substring(0, j));
                    }
                }


            }

            System.out.println("Tries made!");
            lexBuff.close();

            lexBuff=new BufferedReader(new FileReader(testDataFile));

            while((strLine=lexBuff.readLine())!=null)
            {
                temp=strLine.split(" ");

                for(i=0;i<temp.length;i++)
                {
                    reverse=new StringBuffer(temp[i]).reverse().toString();

                    if(reverse.length()<4)
                    {
                        continue;
                    }

                    maxInfoRev=revTrie.frequency(reverse.substring(0, 2))-revTrie.frequency(reverse.substring(0, 3));
                    kidLength=2;
                    maxKidDiff=0;
                    maxM=0;
                    height=length=temp[i].length();

                    for(j=1;j<temp[i].length();j++)
                    {
                        infoRev=revTrie.frequency(reverse.substring(0, j))-revTrie.frequency(reverse.substring(0, j+1));

                        kidDiff=revTrie.children(reverse.substring(0,j))-revTrie.children(reverse.substring(0, j+1));

//                        if(infoRev>=maxInfoRev)
//                        {
//                            maxInfoRev=infoRev;
//                            kidLength=j;
//                        }
//                        if(kidDiff>maxKidDiff)
//                        {
//                            maxKidDiff=kidDiff;
//                            kidLength=j;
//                        }
                        m=alpha*infoRev+beta*kidLength+gamma*height;
                        height--;
                        if(m>maxM)
                        {
                            length=j;
                            maxM=m;
                        }
                    }



                    //System.out.println(temp[i]+":"+reverse+":"+new StringBuffer(reverse.substring(0, length)).reverse().toString()+"-"+new StringBuffer(reverse.substring(length, reverse.length())).reverse().toString());
                    obuff.write(temp[i]+":"+reverse+":"+new StringBuffer(reverse.substring(0, length)).reverse().toString()+"-"+new StringBuffer(reverse.substring(length, reverse.length())).reverse().toString()+"\n");
                }

            }


        }catch(FileNotFoundException ex)
        {
            ex.printStackTrace();
        }catch(IOException ex)
        {
            ex.printStackTrace();
        }
    }

    public void testStemming(double alpha, double beta, double gamma, double threshold, String inFileName)
    {
        File inFile=new File(inFileName);
        File lexicon=new File("lexicon.txt");
        File output=new File("output.txt");
        File errorFile=new File("errors.txt");

        
        String strLine=new String();
        String []temp=null;
        String reverse=new String();

        HashMap wordsAndSuffixes=new HashMap();

        ViewableTrie wordsTrie=new ViewableTrie(false);
        ViewableTrie revTrie=new ViewableTrie(false);

        int kids, kidsofkid, maxKidDiff, kidDiff, kidLength;
        int i, j, infoLength, infoRev, maxInfoRev;
        int infoNormal, maxInfoNormal;
        int length=0;
        int height;

        int numberOfKids;

        int total=0, correct=0;

        double m, maxM, minM;

        Pattern p=Pattern.compile("([\u0A80-\u0AFF]+)(\t+)([\u0A80-\u0AFF]+)\\+([\u0A80-\u0AFF]+)");
        Pattern consonant=Pattern.compile("[\u0A85-\u0AB9]");

        Matcher match;
        Matcher consonantMatch;


        

        try
        {
            BufferedReader lexBuff=new BufferedReader(new FileReader(lexicon));
            BufferedReader testBuff=new BufferedReader(new FileReader(inFileName));
            BufferedWriter outBuff=new BufferedWriter(new FileWriter(output, true));
            BufferedWriter errorBuff=new BufferedWriter(new FileWriter(errorFile));

            while((strLine=lexBuff.readLine())!=null)
            {
                temp=strLine.split(" ");

                for(i=0;i<temp.length;i++)
                {
                    for(j=1;j<temp[i].length();j++)

                    {
                        wordsTrie.insert(temp[i].substring(0, j));
                    }
                    reverse=new StringBuffer(temp[i]).reverse().toString();

                    for(j=1;j<reverse.length();j++)
                    {
                        revTrie.insert(reverse.substring(0, j));
                    }
                }

            }

            while((strLine=testBuff.readLine())!=null)
            {
                match=p.matcher(strLine);
                if(match.matches()==false)
                {
                    continue;
                }

                reverse=new StringBuffer(match.group(0)).reverse().toString();

                for(j=1;j<reverse.length();j++)
                {
                        revTrie.insert(reverse.substring(0, j));
                }

                //System.out.println(strLine);

                if(match.group(0)==null || match.group(3)==null)
                {
                    continue;
                }

//                System.out.println(match.group(1)+"-------"+match.group(4));

                wordsAndSuffixes.put(match.group(1), match.group(4));

            }

            for(Iterator iter=wordsAndSuffixes.keySet().iterator();iter.hasNext();)
            {

                    String word=iter.next().toString();
                    //System.out.println(word);

                    reverse=new StringBuffer(word).reverse().toString();

                    if(reverse.length()<4)
                    {
                        continue;
                    }

                    maxInfoRev=revTrie.frequency(reverse.substring(0, 2))-revTrie.frequency(reverse.substring(0, 3));
                    kidLength=2;
                    maxKidDiff=0;
                    maxM=0;
                    minM=50;
                    height=length=word.length();

                    numberOfKids=revTrie.children(reverse.substring(0, 1));

                    for(j=1;j<word.length();j++)
                    {



                        System.out.println(word+":"+j+":"+reverse.substring(0, j)+":"+revTrie.frequency(reverse.substring(0, j))+":"+revTrie.children(reverse.substring(0, j)));

                        if(revTrie.children(reverse.substring(0, j))<=numberOfKids)
                        {
                            numberOfKids=revTrie.children(reverse.substring(0, j));
                        }
                        else
                        {
                            length=j;
                            break;
                        }

                        infoRev=revTrie.frequency(reverse.substring(0, j))-revTrie.frequency(reverse.substring(0, j-1));

                        kidDiff=revTrie.children(reverse.substring(0,j))-revTrie.children(reverse.substring(0, j-1));

//                        if(infoRev>=maxInfoRev)
//                        {
//                            maxInfoRev=infoRev;
//                            kidLength=j;
//                        }
//                        if(kidDiff>maxKidDiff)
//                        {
//                            maxKidDiff=kidDiff;
//                            kidLength=j;
//                        }


                        m=alpha*infoRev+beta*kidDiff+gamma*height;
                        height--;
                        if(m>maxM)
                        {
                            length=j;
                            maxM=m;
                        }
                        if(m<minM)
                        {
                            minM=m;
                        }

                        


                    }

                    consonantMatch=consonant.matcher(reverse.substring(length));

                    while(length==1)
                    {
                        length++;
                    }

                    //System.out.println(length+":"+new StringBuffer(reverse.substring(0, length)).reverse().toString()+"---"+wordsAndSuffixes.get(word));

                    

                    if(new StringBuffer(reverse.substring(0, length)).reverse().toString().equals(wordsAndSuffixes.get(word).toString()))
                    {
                        correct++;
                    }
                    else
                    {
                        System.out.println(word+":"+new StringBuffer(reverse.substring(0, length)).reverse().toString()+":"+length+":"+wordsAndSuffixes.get(word).toString());
                    }

                    total++;
            }


        //System.out.println("Total: "+total+" Correct: "+correct);

        outBuff.write(alpha+":"+beta+":"+gamma+":"+total+":"+correct+"\n");

        outBuff.close();
        lexBuff.close();
        testBuff.close();

        }catch(IOException ex)
        {
            ex.printStackTrace();
        }
    }


}
